{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
\n",
" Si c'est votre première visite dans ce TP, lisez attentivement chacun des points détaillé après ce paragraphe.
\n",
" Si vous avez déjà commencer à travailler sur ce TP et que vous souhaiter vous déplacer rapidement dans une partie précise vous pouvez choisir la partie que vous souhaitez rejoindre ci-dessous.
\n",
" Menu de navigation
\n",
" \n",
"
\n",
"
\n",
" La technologie jupyter permet d'exécuter du code python par un simple clique sur Executer ci-dessus.
\n",
" Les morceaux de code de cette page sont interprétées case par case. Pour savoir quelle case a été interprétée avant une autre, il suffit de repérer le numéro devant la case.
\n",
" Une fois qu'une case a été interprétée (=exécutée), la page garde en mémoire les variables et fonctions lues
\n",
" La plateforme propose quelques outils de purge de la mémoire : \n",
"
\n",
" Pour ne pas perdre votre travail pensez à le sauvegarder régulièrement. Par défault, la sauvegarde par un clic sur la disquette en haut à gauche de page, ou par le racourci clavier classique ctrl+S
\n",
" est une sauvegarde en local, sur le serveur de jupyter. Vous pouvez et devez très régulièrement sauvegarder votre travail sur votre support personnel de sauvegarde (clef USB, se l'envoyer par mail etc). Ce faisant vous disposerez d'un fichier .ipynb (IPYthon NoteBook) qu'il vous suffira de recharger pour avancer. Après le rechargement assurez vous que les fonctionnalités anciennement developpées et variables utilisées sont bien dans la mémoire de la page (en rééxecutant les cases, ou plus rapidement par Kernel > Restart & Run All.
A NOTER : vous pouvez travailler sur le tp (et tout autre fichier .ipynb) hors connexion en installant une version local du notebook de jupyter. Il faut que votre machine possède un interpreteur de python et que vous soyez connecter à internet.\n", "
pip install jupyterlab
jupyter notebook
Comme pour le TP1, TP2 et TP3, une bibliothèque regroupant quelques outils de la cryptologie vous ont été donnée. Chargeons l'intégralité des fonctionnalités qu'elle propose
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from OutilsCrypto import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vous êtes invité à travailler sur la première partie du TP1 pour vous refamiliariser avec les fonctionnalités de cette bibliothèque comme codex
, codex
, xedoc
, paquet
, mode2base
, Filtre
ainsi que les fonctions d'attaque par dictionnaire.
\n",
" Menu de navigation
\n",
" \n",
"
\n",
"
L'objectif de cette section est de comparer en temps (et implicitement en mémoire) différent alogorithme déterministe de primalité. Exécuter la case suivante, qui donner quelques nombre premier.
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Petit_premier=[2, 13, 557, 1223, 99829, 125017]\n", "Grand_premier=[524287, 2147483647, 987012377731]\n", "Ultra_premier=[2**61-1, 2**89-1]\n", "print(Petit_premier)\n", "print(Grand_premier)\n", "print(Ultra_premier)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "D'après la définition, un nombre est premier si il n'a que deux diviseurs. Ecrire la fonction diviseurs(n)
qui retourne la liste des diviseurs de n
En déduire un premier test de primalité qui renvoie True
si le nombre est premier et False
sinon.
L'inconvénient de la méthode précédente est qu'elle stocke la liste de diviseur dans une variable. Dans la pratique cela n'est pas nécessaire. Ecrire la fonction Primal2(n)
qui renvoie True
si le nombre est premier et False
sinon, en essayant de diviser n
par tous les entiers entre $2$ et $n-1$.
Comme le montre le dernier test (que vous devriez intérompre, par ce qu'il fini dans longtemps : dans le menu supérieur cliquez sur Kernel
puis Interupt
), le temps de calcul pour des nombre premier supérieur à $10^6$ explose. Cependant nous avons vu en cours, qu'il n'est pas nécessaire de tester tous les nombre entre $2$ et $n-1$. Il suffit en effet de s'arreter à la partie entière de $\\sqrt{n}$. Ecrire la fonction Primal3(n)
qui renvoie True
si le nombre est premier et False
sinon, en essayant de diviser n
par tous les entiers entre $2$ et la partie entière de $\\sqrt{n}$.
En python, la racine carré d'un nombre s'obtient par la fonction math.sqrt
.
On peut encore diviser le temps de calcul par au moins 2 puisqu'en effet, seul le nombre 2 est paire. Au lieu de tester la division par tous les nombres entre $2$ et la partie entière $\\sqrt{n}$, il suffit de commencer à $3$ et de tester un nombre sur deux. Ecrire la fonction Primal4(n)
prennant en compte cette considération.
Si vous avez un peu de temps, amusez-vous à exécuter la troisème case... si vous l'osez !
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for n in Petit_premier : \n", " top=time.time()\n", " x=Primal4(n)\n", " temps=round(time.time()-top, 3)\n", " print(\"Test de primalité sur\", n, \":\",x, \"(\", temps, \"s)\" )" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for n in Grand_premier : \n", " top=time.time()\n", " x=Primal4(n)\n", " temps=round(time.time()-top, 3)\n", " print(\"Test de primalité sur\", n, \":\",x, \"(\", temps, \"s)\" )" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for n in Ultra_premier : \n", " top=time.time()\n", " x=Primal4(n)\n", " temps=round(time.time()-top, 3)\n", " print(\"Test de primalité sur\", n, \":\",x, \"(\", temps, \"s)\" )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n",
" Menu de navigation
\n",
" \n",
"
\n",
"
Nous avons explorer en TD, le crible d'Eraosthène, qui permet par de simple \"bond\" de se priver de l'opétation % (assez chronophage) et qui donne de plus la liste de tous les nombres premiers inférieur à un nombre donnée.
Ecrire la fonction Erato(n)
qui renvoie cette liste (sans appeler les fonctions précédentes).
Comme nous l'avons explorer en cours, il existe un \"pont de compréhension\" entre d'une part l'unvers des études de fonctions (l'analyse) et la cryptographie (l'arithmétique) à travers la fonction $\\zeta$ de Riemann. Il se trouve que cet illustre mathématicien c'est longtemps intéréssé aux nombres premiers et à leur répartition. Avant d'introduire sa célèbre fonction $\\zeta$, il c'est beaucoup intéréssé au nombre de nombre premier plus petit qu'un nombre donnée. Etant donné un entier $n$, il note $\\pi(n)$ le nombre de nombre premier inférieur ou égale à $n$. L'algorithme d'Eratosthène permet de réprésenter très rapidement cette fonction. Bien avant le formalisme de Riemann, Gauss, alors agé de 16 ans, a observer que ce nombre $\\pi(n)$ se rapprochait de $\\dfrac{n}{ln(n)}$ pour $n$ suffisament grand. Depuis il a été démontré que pour $n$ suffisament grand \n", "$$\\dfrac{n}{ln(n)-\\frac{3}{2}}<\\pi(n)<\\dfrac{n}{ln(n)-\\frac{1}{2}}$$\n", "
\n", "\n",
"La fonction FonctionPi(xmin, xmax)
trace la focntion $n\\mapsto \\pi(n)$ ainsi que les deux fonctions d'encadrement. En l'utilisant et par observation graphique, détermner le plus petit entier $N$ tel que \n",
" $$\\forall n\\geqslant N, \\quad\\dfrac{n}{ln(n)-\\frac{3}{2}}<\\pi(n)<\\dfrac{n}{ln(n)-\\frac{1}{2}}$$\n",
"(Il est plus petit que 100)\n",
"
\n",
" Menu de navigation
\n",
" \n",
"
\n",
"
Ecrire la fonction EMR(x, n, m)
permettant, comme détaillé dans le cours, de calculer l'exponentiation modulaire rapide $x^n\\ mod\\ m$.
\n",
" Menu de navigation
\n",
" \n",
"
\n",
"
Commençont par déterminer la taille des paquet. On rappel que si $26\\leqslant n<2526$ alors on sera en paquet de 1, si $2526\\leqslant n<252526$ alors on sera en paquet de 2, etc.
Ecrire la fonction taille_paquet(n)
qui renvoie la taille du paquetage.
Ecrire la fonction ERSA(txt, clef)
qui prend en paramètre un texte claire txt
et une clef publique du chiffrement RSA clef
qui est un tableau à deux cases (la case 0 est le \"$n$\" et la case 1 est le \"$e$\") et qui renvoie le message chiffré suivant le cryptosystème RSA.
Ecrire la fonction DRSA(txt, clef)
qui prend en paramètre un texte chiffré suivant le cryptosystème RSA txt
et la clef privée de déchiffrement clef
qui est un tableau à deux cases (la case 0 est le \"$n$\" et la case 1 est le \"$d$\") et qui renvoie le message claire.
Reprenez les fonctions deu TP2 permettant de calculer le PGCD entre deux nombres et l'inverse modulaire
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def PGCD(a, b) :\n", " return 0" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def inv_mod(a, n) :\n", " return 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ecrire la fonction GenRclef
qui renvoie un tableau asociatif a deux champs : \n",
"